package com.gitee.gen.auto.sql;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;

public class AutoTableScriptGenerator {

	private static final Logger log = LoggerFactory.getLogger(AutoTableScriptGenerator.class);

	private static String DROP_TABLE = "DROP TABLE IF EXISTS %s;\n";
	
	/**
	 * 前缀
	 */
	private static String TABLE_PREFIX = "CREATE TABLE `%s` (\n";

	/**
	 * 后缀
	 */
	private static String SUFFIX_PREFIX = ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='%s';\n";
	
	public static String geneateScript(List<TableScriptDO> list, String sqlFileName) {
		if(CollUtil.isEmpty(list)) {
			return null;
		}
		if(sqlFileName==null) {
			sqlFileName = "gen.sql";
		}
		if(!sqlFileName.toLowerCase().endsWith(".sql")) {
			sqlFileName = sqlFileName + ".sql";
		}
		List<String> tableScriptList = new ArrayList<>();
		for(int i=0; i<list.size(); i++) {
			TableScriptDO tableScriptDO = list.get(i);
			String tableScript = String.format(DROP_TABLE, tableScriptDO.getTableName());
			List<ColumnScriptDO> tableScriptDOs = tableScriptDO.getColumnScriptDOs();
			if(CollUtil.isEmpty(tableScriptDOs)) {
				continue;
			}
			
			String tableCreateScript = String.format(TABLE_PREFIX, tableScriptDO.getTableName());
			tableScript = tableScript + tableCreateScript;
			
			//处理中间的sql脚本生成
			List<ColumnScriptDO> columnScriptDOs = tableScriptDO.getColumnScriptDOs();
			if(CollUtil.isEmpty(columnScriptDOs)) {
				continue;
			}
			//所有字段
			String columns = "";
			String primaryKeyColumn = "";
			for(ColumnScriptDO columnScriptDO : columnScriptDOs) {
				StringBuffer columnScript = new StringBuffer();
				//字段名称
				columnScript.append("    `");
				columnScript.append(columnScriptDO.getColumnName().toLowerCase());
				columnScript.append("` ");
				
				//字段类型
				columnScript.append(columnScriptDO.getType().toUpperCase());
				//字段长度
				if(StringUtils.isNotEmpty(columnScriptDO.getLength()) && checkNeedAddLen(columnScriptDO.getType().toLowerCase())) {
					columnScript.append("(");
					columnScript.append(columnScriptDO.getLength().trim());
					columnScript.append(")");
				}
				
				if(!columnScriptDO.isCanNull()) {
					columnScript.append(" NOT NULL ");
				}
				
				if(columnScriptDO.getDefaultValue()==null) {
					columnScript.append(" DEFAULT '" + columnScriptDO.getDefaultValue() + "' ");
				}else {
					if(columnScriptDO.isCanNull()) {
						columnScript.append(" DEFAULT NULL ");		
					}
				}
				
				if(columnScriptDO.isAutoIncrease()) {
					columnScript.append(" AUTO_INCREMENT ");	
				}
				
				//字段注释
				if(StringUtils.isEmpty(columnScriptDO.getColumnComment())) {
					columnScript.append(",\n");
				}else {
					columnScript.append("COMMENT '");
					columnScript.append(columnScriptDO.getColumnComment());
					columnScript.append("',\n");
				}
				columns = columns + columnScript.toString();
				
				if(StringUtils.isNotEmpty(columnScriptDO.getPrimaryKeyName())) {
					primaryKeyColumn = columnScriptDO.getColumnName();
				}
			}
			tableScript = tableScript + columns;
			
			if(primaryKeyColumn!=null) {
				String primaryKeyScript = "    PRIMARY KEY (`" + primaryKeyColumn + "`)\n";
				tableScript = tableScript + primaryKeyScript;
			}else {
				tableScript = tableScript.substring(0, tableScript.length()-1);
			}
			
			String tableCommentScript = String.format(SUFFIX_PREFIX, tableScriptDO.getTableComment());
			tableScript = tableScript + tableCommentScript + "\n\n";
			tableScriptList.add(tableScript);
		}
		String allScript = "";
		for( String tableScript : tableScriptList) {
			allScript = allScript + tableScript;
		}
		File file = FileUtil.writeBytes(allScript.getBytes(), sqlFileName);
		log.info(file.getAbsolutePath());
		System.out.println(allScript);
		return allScript;
	}

	/**
	 * 检查是否需要添加长度
	 * 
	 * @param columnType
	 * @return
	 */
	private static boolean checkNeedAddLen(String columnType) {
		List<String> type = Arrays.asList(new String[] {"date", 
				"datetime", 
				"text", 
				"timestamp", 
				"json"});
		if(type.contains(columnType)) {
			return false;
		}
		return true;
	}

}
